package dancereal;

public class J26_TypeCasting {
	/* 모든 클래스의 조상
	 * 모든 클래스는 자동적으로 java.lang.Object를 확장함
	 * 즉,Object 클래스는 자바에서 궁극의 super 클래스임
	 * 정의 되어있고, 하위 클래스에서는 이것을
	 * 재정의 해서 적절히 사용 가능
	 * equals - 기존 객체와 매개변수로 전달된 객체와 비교
	 *          객체 비교가 제대로 이뤄질려면 메서드를
	 *          재정의하고 구현해야 함
	 * hashcode - 객체의 해시코드를 출력함
	 *            객체는 일반적으로 heap에 생성됨
	 *            heap에 생성된 객체의 메모리 주소를
	 *            바탕으로 만들어지는 유일한 코드값을 의미
	 *            
	 * toString - 객체에 대한 설명을 출력함
	 * 
	 * 다형성 polymorphism
	 * OOP의 중요 개념 중 하나 
	 * 특정 유형의 프로그래밍 요소(변수)가 상황에 따라 
	 * 다양한 유형의 변수로 바뀔 수 있는 특성을 의미 
	 * 주로 상속관계에 있는 클래스간에서 
	 * 나타나는 특별한 성질 
	 * 
	 * is-a 관계 확인
	 * 특정 객체가 어떤 유형과 동일한지 
	 * 또는 상속 관계인지 알아볼때
	 * instanceof 예약어를 사용
	 */
	
	
	public static void main(String[] args) {
	/*Object obj = new Object();
	
	J25_Animal a = new J25_Animal();
	J25_Fish f = new J25_Fish();
	a = (J25_Animal)new J25_Fish(); // (J25_Animal) 은 상위개념이기에 자동 생략됨
*/	// Fish 는 Animal 을 확장했기 때문에
	// Animal 객체에 Fish 객체를 받을 수 있음
	// 하위 객체를 상위 객체로 cast 하는 경우
	// 이것을 up casting 이라 함
	
	/*f = (J25_Fish)new J25_Animal(); // 괄호의 형변환이 없으면 성립이 안됨
	 * 상위 객체를 하위 객체로 cast 하는 경우
	 * 이것은 down casting 이라 함
	 * 이때 명시적으로 괄호안에 cast 할
	 * 클래스 자료형을 명시
	 * 
	 * 스타크래프트 게임내에서
	 * 해병, 불곰, 의무병을 생산하는 경우
	 * 
	 */
	
	Marine m1 = new Marine();
	Firebat f1 = new Firebat();
	Medic d1 = new Medic();
	
	Human h1 = new Human();
	Wolf w1 = new Wolf();
	Nom n1 = new Nom();

	/* 다형성을 근거로 테란유닛 생산( up casting )
	 * 즉, Marine 유닛은 상황에 따라 
	 * TerranUnits 도 될 수 있다는 의미
	 */
	TerranUnits t1 = new Marine();// up casting
	t1.sayUnit((Marine)t1);
	TerranUnits t2 = new Firebat();// down casting 
	t2.sayUnit((Firebat)t2); 
	TerranUnits t3 = new Medic();
	t3.sayUnit((Medic)t3);
	
	AllianceUnits a1 = new Human();
	AllianceUnits a2 = new Wolf();
	AllianceUnits a3 = new Nom();
	
	// 객체유형 확인하기
	J26_TypeCasting t = new J26_TypeCasting();
	if(t instanceof java.lang.Object)
		System.out.println("t는 Object의 자손");
	
	if (m1 instanceof TerranUnits ) // is - a
		System.out.println("해병은 테란유닛의 자손");
	
	if (m1 instanceof Marine) // 동질성
		System.out.println("m1은 해병임");
	}

}

// TerranUnit - Marine, Firebat, Medic

	class TerranUnits{	
	public void sayUnit(){
		System.out.println("저는 테란 유닛입니다");
	}
	public void sayUnit(Marine m){
		System.out.println("저는 해병 입니다");
	}
	public void sayUnit(Firebat m){
		System.out.println("저는 불곰 입니다");
	}
	public void sayUnit(Medic m){
		System.out.println("저는 의무병 입니다");
	}
	}

	class Marine extends TerranUnits{	}

	class Firebat extends TerranUnits{	}

	class Medic extends TerranUnits{		}
	
	
	 // AllianceUnit - Human, Wolf, Nom

	class AllianceUnits{}

	class Human extends AllianceUnits{}

	class Wolf extends AllianceUnits{}

	class Nom extends AllianceUnits{}
	
